import { isVNode, render, createVNode } from 'vue';
import 'element-plus/es/utils/index.mjs';
import 'element-plus/es/components/config-provider/index.mjs';
import MessageConstructor from './message2.mjs';
import { messageDefaults, messageTypes } from './message.mjs';
import { instances } from './instance.mjs';
import { isString, isFunction } from '@vue/shared';
import { isElement, isNumber } from 'element-plus/es/utils/types.mjs';
import { debugWarn } from 'element-plus/es/utils/error.mjs';
import { isClient } from '@vueuse/core';
import { messageConfig } from 'element-plus/es/components/config-provider/src/config-provider.mjs';

let seed = 1;
const normalizeOptions = (params) => {
    const options = !params || isString(params) || isVNode(params) || isFunction(params) ? { message: params } : params;
    const normalized = {
        ...messageDefaults,
        ...options
    };
    if (!normalized.appendTo) {
        normalized.appendTo = document.body;
    } else if (isString(normalized.appendTo)) {
        let appendTo = document.querySelector(normalized.appendTo);
        if (!isElement(appendTo)) {
            debugWarn("ElMessage", "the appendTo option is not an HTMLElement. Falling back to document.body.");
            appendTo = document.body;
        }
        normalized.appendTo = appendTo;
    }
    return normalized;
};
const closeMessage = (instance) => {
    const idx = instances.indexOf(instance);
    if (idx === -1)
        return;
    instances.splice(idx, 1);
    const { handler } = instance;
    handler.close();
};
const createMessage = ({ appendTo, ...options }, context) => {
    const id = `message_${seed++}`;
    const userOnClose = options.onClose;
    const userOnClick = options.onClick;
    const container = document.createElement("div");
    const props = {
        ...options,
        id,
        onClose: () => {
            userOnClose == null ? void 0 : userOnClose();
            closeMessage(instance);
        },
        onClick: () => {
            userOnClick == null ? void 0 : userOnClick(instance);
        },
        onDestroy: () => {
            render(null, container);
        }
    };
    const vnode = createVNode(MessageConstructor, props, isFunction(props.message) || isVNode(props.message) ? {
        default: isFunction(props.message) ? props.message : () => props.message
    } : null);
    vnode.appContext = context || message._context;
    render(vnode, container);
    appendTo.appendChild(container.firstElementChild);
    const vm = vnode.component;
    const handler = {
        close: () => {
            vm.exposed.visible.value = false;
        }
    };
    const instance = {
        id,
        vnode,
        vm,
        handler,
        props: vnode.component.props
    };
    return instance;
};
const message = (options = {}, context) => {
    if (!isClient)
        return { close: () => void 0 };
    if (isNumber(messageConfig.max) && instances.length >= messageConfig.max) {
        return { close: () => void 0 };
    }
    const normalized = normalizeOptions(options);
    if (normalized.grouping && instances.length) {
        const instance2 = instances.find(({ vnode: vm }) => {
            var _a;
            return ((_a = vm.props) == null ? void 0 : _a.message) === normalized.message;
        });
        if (instance2) {
            instance2.props.repeatNum += 1;
            instance2.props.type = normalized.type;
            return instance2.handler;
        }
    }
    const instance = createMessage(normalized, context);
    instances.push(instance);
    return instance.handler;
};
messageTypes.forEach((type) => {
    message[type] = (options = {}, appContext) => {
        const normalized = normalizeOptions(options);
        return message({ ...normalized, type }, appContext);
    };
});
function closeAll(type) {
    for (const instance of instances) {
        if (!type || type === instance.props.type) {
            // 先移除DOM，在关闭以清除对应的offset
            instance.vnode.el.remove()
            instance.handler.close();
        }
    }
}
message.closeAll = closeAll;
message._context = null;

export { closeAll, message as default };